<?php

namespace app\api\controller;

use app\common\controller\Api;
use think\Cache;
use think\Config;

/**
 * 示例接口
 */
class Wechat extends Api
{
    // 无需登录的接口,*表示全部
    protected $noNeedLogin = ['shareUrl', 'test1'];
    // 无需鉴权的接口,*表示全部
    protected $noNeedRight = ['test2'];

    public function shareUrl()
    {
        $url = $this->request->param('url');
        $orderpostid = $this->request->param('orderpostid');

        if (!$orderpostid){
            $this->error('缺少请求参数');
        }

        //获取完整的支付信息
        $orderPost = Db('orderPost')->where('id', $orderpostid)->find();
        $payCodeLists = Db('payCodeLists')->where('id', $orderPost['pay_code_lists_id'])->find();

        $orderPost['appid'] = $payCodeLists['appid'];
        $orderPost['appsecret'] = $payCodeLists['appsecret'];

        $jssdkconfig = $this->getJssdkConfig($url, $orderPost);
        return json(['status' => 'success', 'data' => $jssdkconfig]);
    }

    public function getJssdkConfig($url = '', $orderPost = [])
    {
        $jsapiTicket = $this->getJsApiTicket($orderPost);
        if ($this->is_error($jsapiTicket)) {
            return $jsapiTicket;
        }
        $nonceStr = $this->generateNonceStr();
        $timestamp = time();
        $url = empty($url) ? $this->getCurrentUrl() : $url;

        $string1 = "jsapi_ticket={$jsapiTicket}&noncestr={$nonceStr}&timestamp={$timestamp}&url={$url}";
        $signature = sha1($string1);

        $config = [
            'appId' => $orderPost['appid'],
            'nonceStr' => $nonceStr,
            'timestamp' => $timestamp,
            'signature' => $signature,
        ];

        if (Config::get('app_debug')) {
            $config['url'] = $url;
            $config['string1'] = $string1;
        }

        return $config;
    }

    public function getJsApiTicket($orderPost)
    {
        $cacheKey = 'wechat_jsapi_ticket_' . Config::get('wechat.uniacid');
        $cache = Cache::get($cacheKey);

        if ($cache && $cache['expire'] > time()) {
            return $cache['ticket'];
        }

        $accessToken = $this->getAccessToken($orderPost);
        if ($this->is_error($accessToken)) {
            return $accessToken;
        }

        $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$accessToken}&type=jsapi";
        $content = $this->httpGet($url);

        if ($this->is_error($content)) {
            $this->error(-1, '获取 jsapi_ticket 失败, 错误信息: ' . $content['message']);
        }

        $result = json_decode($content, true);

        if (empty($result) || $result['errcode'] != 0 || $result['errmsg'] != 'ok') {
            $this->error(-1, '获取 jsapi_ticket 结果错误, 错误信息: ' . $result['errmsg']);
        }

        $record = [
            'ticket' => $result['ticket'],
            'expire' => time() + $result['expires_in'] - 200,
        ];

        Cache::set($cacheKey, $record);

        return $record['ticket'];
    }

    public function getAccessToken($orderPost)
    {
        $cacheKey = 'wechat_access_token_' . Config::get('wechat.uniacid');
        $cache = Cache::get($cacheKey);

        if ($cache && $cache['expire'] > time()) {
            return $cache['token'];
        }

//        $appid = Config::get('wechat.app_id');
//        $secret = Config::get('wechat.app_secret');

        $appid = $orderPost['appid'];
        $secret = $orderPost['appsecret'];

        if (empty($appid) || empty($secret)) {
            $this->error('-1', '未填写公众号的 appid 或 appsecret！');
        }

        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$secret}";
        $content = $this->httpGet($url);

        if ($this->is_error($content)) {
            $this->error('-1', '获取公众号授权失败, 请稍后重试！错误详情: ' . $content['message']);
        }

        $token = json_decode($content, true);

        if (empty($token['access_token']) || empty($token['expires_in'])) {
            $this->error('-1', '获取公众号授权失败！错误代码:' . $token['errcode'] . '，错误信息:' . $token['errmsg']);
        }

        $record = [
            'token' => $token['access_token'],
            'expire' => time() + $token['expires_in'] - 200,
        ];

        Cache::set($cacheKey, $record);

        return $record['token'];
    }

    private function httpGet($url)
    {
        $response = file_get_contents($url);
        if ($response === false) {
            $this->error(-1, '请求失败');
        }
        return $response;
    }

    private function generateNonceStr($length = 16)
    {
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $nonceStr = '';
        for ($i = 0; $i < $length; $i++) {
            $nonceStr .= $chars[mt_rand(0, strlen($chars) - 1)];
        }
        return $nonceStr;
    }

    private function getCurrentUrl()
    {
        return "http://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    }

    function is_error($data) {
        if (empty($data) || !is_array($data) || !array_key_exists('errno', $data) || (array_key_exists('errno', $data) && 0 == $data['errno'])) {
            return false;
        } else {
            return true;
        }
    }
}
